package modele;

import java.awt.Color;
import java.io.Serializable;


/**
 * La classe Segment qui représente un segment grâce a ses deux composition de la classe Point : Origine et Extremite
 * @author Arnaud
 *
 */

public class Segment extends FormeGeometrique implements Serializable {
/**
 * Le premier attribut : Origine
 */
	private Point Origine;
	
	/**
	 * Mutateur de l'attribut Origine
	 * @param origine
	 */
	public void setOrigine(Point origine) {
		Origine = origine;
	}

	/**
	 * Mutateur de l'attribut Extremite
	 * @param extremite
	 */
	public void setExtremite(Point extremite) {
		Extremite = extremite;
	}

	/**
	 * Le deuxieme attribut : Extremite
	 */
	private Point Extremite;
	public boolean is_origine = true;

	/**
	 * Constructeur par défaut de la classe Segment
	 */
	public Segment() {
		this.Origine=null;
		this.Extremite=null;
	}

	/**
	 * Constructeur canonique de la classe Segment, va prendre en parametre deux Points
	 * @param a
	 * @param b
	 */
	public Segment(Point a, Point b) {
		Origine = a.createClone();
		Extremite = b.createClone();
	}

	/**
	 * Constructeur de la classe Segment, va prendre en parametre deux Points et une couleur.
	 * @param a
	 * @param b
	 * @param couleur
	 */
	public Segment(Point a, Point b, Color couleur) {
		Origine = a.createClone();
		Extremite = b.createClone();
		this.couleur = couleur;
		
	}

	/**
	 * Méthode permettant d'afficher des informations sur le Segment
	 */
	public String toString() {
		return new String("Coordonnées des points du segment :\n\t"
				+ this.Origine.toString() + "\n\t" + this.Extremite.toString());
	}

	/**
	 * Constructeur secondaire permettant de créer un segment identique(position et couleur)
	 */
	public Segment createClone() {
		Segment Resultat = new Segment(this.Origine.createClone(),this.Extremite.createClone(),this.getCouleur());
		return Resultat;
	}

	/**
	 * Constructeur secondaire qui crée un segment qui est une symetrie par rapport à l'origine
	 */
	public Segment createSymetrieO(Point origine) {
		Segment Resultat = new Segment(this.Origine.createSymetrieO(origine),
				this.Extremite.createSymetrieO(origine), this.couleur);
		return Resultat;
	}
	/**
	 * Constructeur secondaire qui crée un segment qui est une symetrie par rapport à l'axe des abscisses
	 */
	public Segment createSymetrieX(Point origine) {
		Segment Resultat = new Segment(this.Origine.createSymetrieX(origine),
				this.Extremite.createSymetrieX(origine), this.couleur);
		return Resultat;
	}
	/**
	 * Constructeur secondaire qui crée un segment qui est une symetrie par rapport à l'axe des ordonnées
	 */
	public Segment createSymetrieY(Point origine) {
		Segment Resultat = new Segment(this.Origine.createSymetrieY(origine),
				this.Extremite.createSymetrieY(origine), this.couleur);
		return Resultat;
	}
	

	/**
	 La méthode équals retourne un boolean qui vaut TRUE si le segment comparé est identique et FALSE le cas échéant
	 */
	public boolean equals(FormeGeometrique sujet) {
		if (sujet instanceof Segment) {
			return (this.Origine.equals(((Segment)sujet).Origine) && this.Extremite.equals(((Segment)sujet).Extremite));
		} else {
			return false;
		}
	}



	/**
	 * Mutateur qui transforme le segment en sa symetrie par rapport à 0
	 */
	public void symetrieO(Point origine) {
		this.Origine.symetrieO(origine);
		this.Extremite.symetrieO(origine);
	}
	

	/**
	 * Mutateur qui transforme le segment en sa symetrie par rapport à l'axe X
	 */
	
	public void symetrieX(Point origine) {
		this.Origine.symetrieX(origine);
		this.Extremite.symetrieX(origine);
	}

	/**
	 * Mutateur qui transforme le segment en sa symetrie par rapport à l'axe Y
	 */
	public void symetrieY(Point origine) {
		this.Origine.symetrieY(origine);
		this.Extremite.symetrieY(origine);
	}

	// observateurs

	/**
	 * observateur canonique
	 * @return Point origine
	 */
	public Point getOrigine() {
		return this.Origine;
	}
	/**
	 * observateur canonique
	 * @return Point extremite
	 */
	public Point getExtremite() {
		return this.Extremite;
	}

	// autres observateurs
	
	/*
	 * Observateur qui retourne la longueur d'un segment
	 * @return la longueur du segment
	 */
	public double getLongueur() {
		return this.Origine.distance(Extremite);
	}


	@Override
	public double perimetre() {
		return this.getLongueur();
	}

	@Override
	public double surface() {
		return 0;
	}



	@Override
	public void deplacer(Point depart, Point destination) {
		this.Origine.deplacer(depart, destination);
		this.Extremite.deplacer(depart, destination);
	}

	@Override
	public boolean isOnTheClick(Point clic) {
		int marge = 3;
		Point a = this.getOrigine();
		Point b = this.getExtremite();
		return (a.distance(b)<(a.distance(clic)+b.distance(clic))+marge) &&
	            (a.distance(b)>=(a.distance(clic)+b.distance(clic))-marge);
	}

}
